package fr.lip6.meta.ple.generation.fh.java;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.common.util.EList;
import org.eclipse.gmt.modisco.java.AbstractTypeDeclaration;
import org.eclipse.gmt.modisco.java.BodyDeclaration;
import org.eclipse.gmt.modisco.java.ClassDeclaration;
import org.eclipse.gmt.modisco.java.MethodDeclaration;
import org.eclipse.gmt.modisco.java.Model;
import org.eclipse.gmt.modisco.java.Package;
import org.eclipse.gmt.modisco.java.emf.impl.ClassDeclarationImpl;
import org.eclipse.gmt.modisco.java.emf.impl.MethodDeclarationImpl;
import org.eclipse.gmt.modisco.java.emf.impl.PackageImpl;

import artefact.generic.ConstructionPrimitive;
import artefact.umlClassDiagram.CreateOperation;

import fr.lip6.meta.ple.featureIdentification.Feature;
import fr.lip6.meta.ple.generation.strategy.ReadXmiStrategy;
import fr.lip6.meta.ple.plextraction.config.Configuration;
import fr.lip6.meta.tools.*;

public class ReadFeature {
	public void getProductWithSameMethod(ConstructionPrimitive cp, int[]productsids, int prouductidsrc)
	{
		//ArrayList<String> proudectspath=new ArrayList<String>();
	}

	List<ConstructionPrimitive> getCreateOperationCps(Feature f) {
		ArrayList<ConstructionPrimitive> list = new ArrayList<ConstructionPrimitive>();
		
		for(Trigger t : f) {
			StatementPrimitive st = (StatementPrimitive) t;
			
			if (st.getPrimitive() instanceof CreateOperation) {
				list.add(st.getPrimitive());
			}
		}
		
		return list;
	}

	boolean compareMethod(MethodDeclaration m1, MethodDeclaration m2) {
		ReadXmiStrategy readXmi = Configuration.getInstance().getGenerationContext().getReadXmiStrategy();

		if (m1.getParameters().size() != m2.getParameters().size()) {
			return false;
		} else {
			String m1declaration = readXmi.getMethodDeclarationText(m1);
			String m2declaration = readXmi.getMethodDeclarationText(m2);

			if (!(m1declaration.equals(m2declaration))) {
				return false;
			} else {
				String m1body = readXmi.getMethodDeclarationAndBodyText(m1);
				String m2body = readXmi.getMethodDeclarationAndBodyText(m2);

				if (!(m1body.equals(m2body))) {
					return false;
				}
			}
		}

		return true;
	}

	PackageImpl readPackage(String path, String packagename) {
		Model model = GenerateFromXmiFHJava.loadModiscoJavaModel(path);
		Iterator<Package> packages = model.getOwnedElements().iterator();
		PackageImpl p = null;
		
		while (packages.hasNext()) {
			PackageImpl p1 = (PackageImpl) packages.next();

			if(p1.getName().equals(packagename)) {
				p = p1;
				break;
			}
		}

		return p;
	}

	ClassDeclarationImpl readClassDeclaration(String path, String packagename, String classname) {
		ClassDeclarationImpl c = null;
		PackageImpl p = readPackage(path, packagename);

		Iterator<AbstractTypeDeclaration> classs = p.getOwnedElements().iterator();
		
		while (classs.hasNext()) {
			AbstractTypeDeclaration ab = classs.next();
			
			if (ab instanceof ClassDeclaration) {
				ClassDeclarationImpl d = (ClassDeclarationImpl) ab;
				
				if(d.getName().equals(classname)) {
					c = d;
					break;
				}
			}
		}
		
		return c;
	}

	MethodDeclarationImpl readMethodDeclaration(String path, String packagename, String classname, String methodname) {
		MethodDeclarationImpl m = null;
		ClassDeclarationImpl d = readClassDeclaration(path, packagename, classname);
		EList<BodyDeclaration> bodys = d.getBodyDeclarations();
		
		//read body declaration 
		for(BodyDeclaration bo : bodys) {
			if (bo instanceof MethodDeclaration) {
				MethodDeclarationImpl m1 = (MethodDeclarationImpl) bo;
				
				if(m1.getName().equals(methodname)) {
					m = m1;
					break;
				}
			}
		}

		return m;
	}
}
